Глава 21

Тег <CFOBJECT> и технологии COM, CORBA и EJB

Прежде чем описывать работу с тегом <CFOBJECT>, позволяющим вызывать распределенные объекты, построенные на основе таких технологий, как СОМ, CORBA и EJB, приведем некоторые пояснения к каждой из технологий.

СОМ

COM (Component, Object Model, модель многокомпонентных объектов) представляет собой "фундамент", на котором построены технологии ActiveX и OLE. Технология СОМ создавалась фирмой Microsoft как средство взаимодействия приложений (в том числе составных частей операционной системы) Windows, функционирующих на одном компьютере, с последующим развитием для использования в пределах локальной сети. Главная задача на момент создания — обеспечение технологии Object Linking and Embedding (OLE 1.0). Характерно, что обмен данными между приложениями (Dynamic Data Exchange, DDE) первоначально строился не по СОМ-технологии, а с использованием механизма сообщений (messages). Технология развивается по мере добавления новых возможностей. Как универсальная технология взаимодействия приложений, она начала использоваться с OLE 2.0 (1991 г.). Концепция технологии неразрывно связана с ее реализацией. Возникновение новых возможностей — это просто появление новых библиотек, функций API и утилит Windows. "Общий знаменатель" технологии — двоичная структура объекта, хотя в настоящий момент существует язык описания структуры объекта — Interface Definition Language (IDL).

COM содержит все необходимое для построения распределенной системы:

Все составные части прекрасно соответствуют друг другу в рамках модели СОМ. Уникальной возможностью СОМ является универсальная технология доступа к базам данных — OLE ADO DB.

СОМ реализует высокий уровень абстракции — все вопросы низкого уровня, такие как взаимодействие с операционной системой или сетевыми средствами, скрыты от прикладного программиста. Передача данных между клиентом и сервером основана на наборе типов OLE Automation.

CORBA

CORBA (Common Object Request Broker Architecture, универсальная архитектура посредничества при запросе объектов) создавалась консорциумом OMG (Object Management Group). OMG представляет собой некоммерческую организацию, являющуюся содружеством разработчиков программного обеспечения и его потребителей, объединивших свои усилия для создания спецификаций этой технологии. В настоящий момент OMG насчитывает более 800 членов, включая всех сколько-нибудь серьезных производителей программного обеспечения. Первая спецификация CORBA появилась в 1991 г. Новые возможности официально считаются добавленными в CORBA в момент утверждения соответствующей спецификации. Как правило, в разработке спецификации участвуют крупнейшие специалисты в данной области. Разработка реализации — задача конкретной фирмы. Обычно от утверждения спецификации до появления высококачественной-феализации проходит довольно много времени -- иногда несколько лет. "Общий знаменатель" технологии - объявления на языке IDL, который является "сердцем" CORBA с момента ее появления. (Существуют три различных языка описаний с одним и тем же названием — OSF IDL, Microsoft IDL и OMG IDL.)

CORBA так же, как и СОМ, поддерживает статический и динамический способ организации удаленных вызовов и обеспечивает высокий уровень абстракции за счет базирования технологии исключительно на языке описания IDL с последующей трансляцией таких спецификаций на конкретный язык программирования.

EJB и Java

EJB (Enterprise Java Beans) — это спецификация, существенно расширившая возможности первоначальной компонентной модели Java Beans и разработанная в марте 1998 г. корпорацией Sun Microsystems. Если первоначальная модель была предназначена прежде всего для построения компонентов на стороне клиента, то EJB представляет собой фундамент для реализации динамически подключаемых серверных компонентов, которые позволяют расширять функциональность сервера во время выполнения. EJB обеспечивает более высокий уровень взаимодействия — уровень связи между удаленными готовыми компонентами, который, в свою очередь опирается на взаимодействие удаленных объектов клиента и сервера. Для Java-объектов это взаимодействие обеспечивает механизм удаленного вызова методов Remote Method Invocation (RMI), который во многом сходен с CORBA. Сервер объекта скрывает от клиента подробности его реализации, предоставляя доступ к объекту посредством интерфейса, написанного на языке Java.

В спецификации EJB заложена совместимость с CORBA. С другой стороны, в новой CORBA 3.0 присутствует спецификация компонентной модели CORBA Component Model — переход на более высокий уровень построения компонентных объектно-ориентированных приложений непосредственно с помощью CORBA. Причем эта компонентная модель обеспечивает отображение компонентов CORBA в Java Beans. Рассказывая о EJB, нельзя не сказать пару слов о языке программирования Java.

Язык Java произошел от языка программирования Oak, а не от C++, как думают многие. 'Согласно публикациям корпорации Sun Microsystems, выступающей в качестве разработчика языка Java, Oak был приспособлен для работы в Internet и затем переименован в Java.

Язык Java является объектно-ориентированным и поставляется с достаточно объемной библиотекой классов. Так же, как и библиотеки классов систем разработки приложений на языке C++, библиотеки классов Java значительно упрощают разработку приложений, предоставляя в распоряжение программиста мощные средства решения распространенных задач. Поэтому программист может больше внимания уделить решению прикладных задач, а не таких, как, например, организация динамических массивов, взаимодействие с операционной системой или реализация элементов пользовательского интерфейса.

Так вот ColdFusion в свою очередь позволяет вызывать распределенные объекты как на основе технологий COM, CORBA, EJB, так и объекты Java, при помощи тега <CFOBJECT>, описание которого мы рассмотрим ниже.

Тег <CFOBJECT>

Синтаксис тега <CFOBJECT> зависит от типа, определямого с помощью атрибута TYPE, который может принимать следующие значения:

Судя по названию типа нетрудно догадаться, вызов объекта на основе какой технологии будет при этом использован.

Далее приведем синтаксис для каждого типа тега <CFOBJECT> и затем в табл. 21.1 объединим описание возможных атрибутов.

Синтаксис с вызовом объекта СОМ:

<CFOBJECT TYPE = "COM"

NAME = "object name"

ACTION = "Create | Connect"

CLASS = "program_ID"

CONTEXT = "InProc | Local | Remote"

SERVER = "server_name">

Синтаксис с вызовом объекта CORBA:

<CFOBJECT TYPE = "CORBA"

NAME = "object name" CLASS = "file or naming service"

CONTEXT = "IOR | NameService" LOCALE = "type-value arguments">

Синтаксис с вызовом объекта EJB или Java:

<CFOBJECT TYPE = "Java"

NAME = "object name" ACTION = "Create" CLASS = "Java class">

Таблица 21.1. Описание атрибутов тега <CFOBJECT>

Атрибут

Описание

ACTION

Действие. Обязательный атрибут для СОМ и Java и абсолютно неприменим для CORBA. Возможные значения для СОМ:

  • Create — создание объекта; данное значение также используется для EJB или Java;
  • Connect — соединение с объектом. Например:

<CFTRY> <CFOBJECT TYPE="COM" ACTION="Connect"

CLASS="Word. Application"

NAME="objWord"> <CFCATCH> <CFOBJECT TYPE="COM" ACT ION= "Create" CLASS="Word. Application"

 

Атрибут

Описание


NAME="objWord"> </CFCATCH> </CFTRY>

В представленном фрагменте кода если происходит ошибка на момент соединения с объектом, то, следовательно, данный объект не существует и его необходимо создать. Это, собственно говоря, мы и реализуем в блоке обработки ошибок

CLASS

Класс. Обязательный атрибут для всех типов.

Для СОМ подразумевает использование уникального кода или наименования компонента подключаемого объекта.

Для CORBA указывается в зависимости от контекста, определяемого атрибутом CONTEXT. Например:

<CFOBJECT TYPE="CORBA" NAME="GetName" CONTEXT="IOR" CLASS="c: \\myob ject.ior">

Для EJB или Java имя атрибута говорит само за себя — с помощью данного атрибута определяется класс Java

NAME

Имя, по которому в дальнейшем предполагается обращение к созданному объекту. Обязательный атрибут для всех типов

CONTEXT


Контекст, определяет характер доступа. Необязательный атрибут для СОМ и необходимый для CORBA.

Для СОМ может принимать следующие значения:

  • inProc — смешанный;
  • Local — локальный;
  • Remote — удаленный.

Для CORBA может принимать следующие значения:

  • IOR— используется Interoperable Object Reference (интероперабельная объектная ссылка) для доступа к CORBA-серверу;
  • NameService— используется наименование сервиса для доступа к серверу

SERVER

Сервер. Необходимо указывать в сочетании с контекстом только для СОМ. Может принимать одну из следующих форм:

 

Атрибут

Описание

LOCALE

Устанавливает аргументы для обращения к init orb(). Необязательный атрибут и если используется, то только для CORBA. Указание этого атрибута определяет VisiBroker orbs* и в настоящее время доступно на C++ версии 3.2. При этом атрибут должен иметь следующий вид:

  • ORBagentAddr 199.99.129.33
  • ORBagentPort 19000" где каждая пара значений должна начинаться с дефиса (-)

* VisiBroker orbs — это программный продукт, обеспечивающий полную поддержку спецификации CORBA.

Примеры вызова распределенных объектов

Что касается выбора распределенных объектов COM, CORBA или EJB, то автор не ставит перед собой цель склонить читателя к той или иной технологии. Например, для проектов средней сложности в среде Windows конечно следует использовать СОМ-технологию, тем более что в упомянутой операционной системе для этого все уже готово. Для сложных же масштабируемых проектов или при использовании гетерогенных сред, возможно, следует применять CORBA-технологию. Впрочем, и о EJB не стоит забывать. Однако в силу простоты демонстрации и привычки, выработанной годами, мы рассмотрим примеры вызова объектов Java и объектов, построенных по технологии СОМ.

Java-объекты

Прежде чем вызвать объект Java, его необходимо создать. Предположим, что требуется создать некий Java-объект, позволяющий производить определенные математические действия над двумя передаваемыми величинами. Для решения данной задачи формируем Java-код Calculation.Java, представленный в листинге 21.1.

Листинг 21.1. Java-код Calculation.java

public class Calculation { public int x, y; public Calculation()

{ this.у = 1;

this.x = 1; }

public int Sum(int x, int y) (return x+y;}

public int Subtraction(int x, int y) {return x-y;}

public int Multiplication(int x, int y) {return x*y;}

public int Division(int x, int y) (return x/y;} }

где х и у — принимаемые в качестве параметров величины. Здесь также объявлены четыре метода, соответствующие каждому из математических действий: Sum (суммирование), subtraction (вычитание), Multiplication (умножение) и Division (деление). Для данного кода было бы уместно включить определенные проверки (например, деление на ноль). Однако, дорогой читатель, все в ваших руках. А нам, между тем, необходимо продемонстрировать вызов данного объекта из ColdFusion.

Но перед тем как мы вызовем данный объект, надо бы совершить еще одно действие, а именно откомпилировать исходный текст Java из файла Calculation.jav<a в байт-код Java-файла Calculation.class. Для подобных целей в Java существует компилятор javac.exe. В нашем случае следует выполнить команду:

Javac D:\CFUSION\Java\classes\Calculation.java

Данная команда предполагает, что наш класс размещается в каталоге D:\CFUSION\Java\classes\, и для удобства использования новых классов этот каталог мы устанавливаем как месторасположение динамически загружаемых Java-классов (Dynamic Class Load Path), что позволяет не перезагружать службу ColdFusion для отображения очередных изменений, произведенных по отношению к выполняемому Java-классу.

Более подробно о настройках Java с использованием страницы администратора "ColdFusion Administrator" см. главу 14.

И теперь, когда подготовительная работа проведена, остается создать CFML-страницу, позволяющую вызвать объект Java и использовать существующие методы по назначению (листинг 21.2).

Листинг 21.2. Код страницы MyCFObjectJava.cfm

<HTML> <HEAD>

<TITLE>CFOBJECT Java</TITLE> </HEAD>

<BODY>

<CFOBJECT TYPE="Java"

ACTION="Create"

CLASS="Calculation" NAME="myCalc">

<CFSET myCalc.x = 10>

<CFSET myCalc.y = 5>

<CFSET x = myCalc.x>

<CFSET у = myCalc.y>

<CFSET ResultSum = myCalc.Sum(x, y)>

<CFSET ResultSubtraction = myCalc.Subtraction(x, y)>

<CFSET ResultMultiplication = myCalc.Multiplication(x, y)>

<CFSET ResultDivision = myCalc.Division(x, y)>

<CFSCRIPT>

WriteOutput('x = ' & x & '; у = ' & y);

WriteOutput{'<br>Sum = ' & ResultSum);

WriteOutput('<br>Subtraction = ' & ResultSubtraction);

WriteOutput('<br>Multiplication = ' & ResultMultiplication);

WriteOutput('<br>Division = ' & ResultDivision); </CFSCRIPT>

</BODY>

</HTML>

В результате выполнения представленной страницы будет выведено:

х = 10; у = 5

Sum = 15

Subtraction = 5

Multiplication = 50

Division = 2

К этому, собственно говоря, мы и стремились.

СОМ-объекты

Смысл использования объектов, построенных по технологии СОМ, заключается в следующем. В операционной системе зарегистрированы программы, которые могут выступать в роли СОМ-объектов, предоставляющих другим программам возможности использования своих объектов. ColdFusion может выступать в роли одной из таких программ, использующих СОМ-объекты других приложений. Впрочем, вы также можете создавать собственные СОМ-объекты, но мы в нашем примере будем вызывать уже существующие распределенные объекты, тем более что особого дефицита в СОМ-объектах в среде Windows нет. Если учесть, что только от Microsoft их несколько десятков.

Предположим, что нам необходимо поместить данные из существующей базы данных Cruise в файл Microsoft Excel, используя при этом доступ к базе данных с помощью объекта ADO DB (ActiveX Data Objects DataBase). Отметим, что ADO DB представляет собой объект, являющийся неотъемлемой частью библиотеки типов ADO (ActiveX Data Objects) от Microsoft, и применяется для разработки соединений баз данных, выполнения команд и извлечения наборов данных из источников.

Как уже было отмечено в описании тега <CFOBJECT>, в качестве атрибута CLASS при использовании турe="com" необходимо указывать уникальный код или название компонента подключаемого объекта. И прежде чем формировать CFML-страницу с вызовом распределенного объекта, необходимо выяснить этот самый уникальный код или имя объекта.

В общем, здесь есть несколько путей, один из них — обратиться непосредственно к редактору реестра (Regedit.exe) и в разделе HKEY_CLASSES_ROO;I\CLSID\, просмотрев список СОМ-объектов, найти необходимый код объекта. Однако, если у вас установлен пакет Microsoft Visual Studio версии 6.0, то просмотр зарегистрированных СОМ-объектов легко решается с помощью утилиты OLE/COM Object Viewer (Oleview.exe).

Перед тем как продемонстрировать работу с инструментом просмотра OLE-и СОМ-объектов, хотелось бы внести некоторое пояснение к работе с базами данных при использовании ADO DB. При подключении существующей базы данных необходимо применить метод open коллекции Connection объекта ADO DB, после чего следует создать ссылку на набор данных с использованием метода Open только уже коллекции Recordset все того же объекта ADO DB.

На примере коллекции connection объекта ADO DB найдем необходимый для вызова объекта — уникальный код и научимся определять синтаксис методов, где важно правильно задать значения, передаваемые в качестве параметров.

Для работы с программой просмотра OLE- и СОМ-объектов в качестве первого шага необходимо запустить программу Oleview.exe, расположенную в папке X:\Program File\Microsoft Visual Studio\Common\Tools\, где X является устройством, куда была установлена программа MS Visual Studio 6.0. После запуска OLE/COM Object Viewer выберем пункт All Objects (Все объекты).

Следующим шагом находим сам объект ADODB.connection.

Как видно, здесь же указан тот самый уникальный код объекта, который нет необходимости запоминать, достаточно щелкнуть правой кнопкой мыши по имени объекта и из контекстного меню выбрать команду Copy CLSID to Clipboard (Скопировать код в буфер обмена). В нашем случае в буфере обмена будет помещен следующий фрагмент:

{00000514-0000-0010-8000-00AA006D2EA4}

Теперь можно смело создать код, позволяющий вызывать объект ADO DB с коллекцией Connection:

<CFOBJECT TYPE="COM"

ACTION="Create"

CLASS="{00000514-0000-0010-8000-OOAA006D2EA4}"

NAME="objConn">

Конечно, можно было бы написать иначе, например:

<CFOBJECT TYPE="COM"

ACTION="Create" CLASS="ADODB.Connection" NAME="objCom">

В последнем фрагменте выполнено обращение к объекту по имени ADODB.Connection, но заметьте, и при этом каждый имеет свой уникальный номер и использует собственную версию библиотеки (msadol0.dll и msadol5.dll). Где гарантия, что в последнем случае использования тега <CFOBJECT> будет вызван именно тот СОМ-объект, который вам необходим? То же относится и к объекту ADODB.Recordset. А вот объект офисного приложения MS Excel можно смело вызывать по имени — Excel.Application.

Например:

<CFOBJECT TYPE="COM"

ACTION="Create"

CLASS="Excel.Application" NAME="objExcel">

Если вы прочитали предыдущую главу, то знаете, что в CFML-страницах" можно использовать CFScript, и нам ничто не мешает вызвать объект

Excel. Application с помощью функции CreateObject внутри блока

<CFSCRIPT>, как показано в следующем примере:

<CFSCRIPT>

objExcel = CreateObject("COM", "Excel.Application"); </CFSCRIPT>

Впрочем, вернемся к инструменту просмотра OLE- и СОМ-объектов. Дело в том, что мало вызвать объект, по отношению к нему надо совершать какие-либо действия. И для просмотра этих самых действий в виде методов, надо выполнить следующее:

  1. В контексте выбранного объекта выделить подраздел, например все для того же ADODB.Connection выделить IDispatch.
  2. Щелкнув по выбранному подразделу правой кнопкой мыши, выбрать команду View (Просмотр).
  3. В открывшемся диалоговом окне нажать кнопку View Typelnfo (Просмотр информации о типе).
  4. В появившемся окне ITypelnfo Viewer (Просмотр информации о типе) раскрыть список методов (Methods) и выбрать необходимый для изучения метод.

Как видно, методу open объекта ADODB.connection в качестве передаваемых параметров необходимо назначить:

Например по Internet-адресу http://msdn.microsoft.com/ library/default.asp?url=/library/en-us/ado270/htm/mdcstlocktypeenum.asp можно узнать, что режим соединения способен принимать два значения: —1 (synchronously (синхронный)) и 16 (asynchronously (асинхронный)).

Очередной пример демонстрирует вызов объекта ADODB.connection с последующим открытием соединения в синхронном режиме:

<CFOBJECT TYPE="COM"

ACTTON="Create"

CLASS = "{00000514-0000-0010-8000-OOAA006D2EA4}"

NAME="objConn">

<CFSCRIPT>

objConn.Open("Cruise", "dba", "sql", -1};

</CFSCRIPT>

Если вы еще не забыли, что изначально перед нами стояла задача поместить данные из существующей базы данных Cruise в файл Microsoft Excel, осуществляя при этом доступ к базе данных с помощью объекта ADO DB, то самое время об этом вспомнить. И теперь, когда вы имеете некоторое представление об использовании СОМ-объектов, представим листинг решения описанной задачи.

Листинг 21.3. Код страницы MyCFObjectCOM.cfm

<HTML> <HEAD>

<TITLE>CFOBJECT COM</TITLE> </HEAD>

<BODY>

<CFOBJECT TYPE="COM"

ACTION="Create" CLASS="Excel.Application" NAME="objExcel">

<!--- ADODB.Connection --->

<CFOBJECT TYPE="COM"

ACTION="Create"

CLASS = "{00000514-0000-0010-8000-OOAA006D2EA4}" NAME="objConn">

<!— ADODB. Recordset —> <CFOBJECT TYPE="COM"

ACTION="CREATE "

CLASS="{00000535-0000-0010-8000-OOAA006D2EA4}"

NAME="objRecord">

<CFSCRIPT>

// Определение наименования и месторасположения файла File = "Cruise.xls";

FilePath = GetDirectoryFromPath(GetCurrentTemplatePath()) & File;

if (FileExists(FilePath) EQ "true") {

WriteOutput("File: '" & FilePath & "' exist!"); } else {

pmCursorType = 3; pmLockType = 1; pmOptions = 1; pmRows = -1;

// Открытие соединения ADO DB и выполнение запроса"

objConn.Open("Cruise", "dba", "sql", -1);

strSQL = "SELECT Name__tou, PointDepart=tou FROM Tour";

objRecord.Open(strSQL, objConn, pmCursorType,

pmLockType, pmOptions); // Создание объекта Excel

objWorkBook = objExcel.Workbooks;

objOpenedBook = objWorkBook.Add();

objWorkSheets. = objExcel.Worksheets;

objWorkSheet = objWorkSheets.Add();

// Получение данных

arRows = objRecord.GetRows(pmRows);

// Формирование шапки таблицы в Excel

objRange = objExcel.Range("Al");

objRange.ColumnWidth = 25;

objRange = objExcel.Range("Bl");

objRange.ColumnWidth = 30;

objRange = objExcel.Range("Al:A1");

objRange.Value = "Name Tour";

objRange = objExcel.Range("Bl:B1");

objRange.Value = "Point Depart";

// Цикл заполнения данными в Excel

iCurRow => 1; while (iCurRow LE objRecord.RecordCount) (

for (ICurCol = 1; ICurCol LE 2;

iCurCol = iCurCol+1) { iCurRowExl = iCurRow + 1;

iCurColExl = liffiCurCol EQ 1,DE("A"),DE("B"));

objRange = objExcel.Range("tiCurColExl#

#iCurRowExl#:#iCurColExl##iCurRowExl#");

objRange.Value = arRows[iCurCol][iCurRow]; }

iCurRow = iCurRow + 1; }

// Сохранение файла Excel и закрытие созданных объектов objWorkSheet.SaveAs(FilePath, Val(l)); objWorkBook.Close();

objExcel.Quit(); objExcel = "Nothing";

objRecord.Close(); obj Conn.Close(); }

</CFSCRIPT> <META HTTP-EQUIV="Refresh"

CONTENT="0;URL=<CFOUTPUT>#File#</CFOUTPUT>">

</BODY> </HTML>

В качестве самостоятельной работы можете изучить такие СОМ-объекты, как:

Резюме

Подведем итог. В данной главе мы использовали CFML-тег <CFOBJECT>.